package com.dd.keel.core.beans.factory;

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import org.springframework.beans.BeansException;
import org.springframework.context.ApplicationContext;
import org.springframework.context.support.ClassPathXmlApplicationContext;

/**
 * Thre factory for initializing the spring context
 * @author Kevin.XU
 *
 */
public class KeelBeanFactory {
	
	final static private Logger LOGGER = LoggerFactory.getLogger(KeelBeanFactory.class);
	
	private static ClassPathXmlApplicationContext classPathXmlApplicationContext = null;
	
	public static ApplicationContext getApplicationContext()
	{
		return classPathXmlApplicationContext;
	}
	
	public static void init(String beansLocations) throws KeelBeanException
	{
		if(beansLocations==null) throw new KeelBeanException("Bean config file location is required!");
		beansLocations = beansLocations.trim();
		if(beansLocations.equals("")) throw new KeelBeanException("Bean config file location is required!");
		LOGGER.info("Begin to init .........");
		String[] beans_config_array = null; 
		if(beansLocations.indexOf(',')!=-1)
		{
			beans_config_array = beansLocations.split(",");
		}
		else if(beansLocations.indexOf('|')!=-1)
		{
			beans_config_array = beansLocations.split("\\|");
		}
		else
		{
			beans_config_array = new String[]{beansLocations};
		}
		if(beans_config_array==null) throw new KeelBeanException("separation must use ',' or '|' ");
		LOGGER.info("Loading beans config files ...");
		for(int i=0; i<beans_config_array.length; i++)
		{
			LOGGER.info("[{}]",beans_config_array[i]);
		}
		classPathXmlApplicationContext = new ClassPathXmlApplicationContext();
		classPathXmlApplicationContext.setId("keel");
		classPathXmlApplicationContext.setConfigLocations(beans_config_array);
		classPathXmlApplicationContext.refresh();
		classPathXmlApplicationContext.registerShutdownHook();
		LOGGER.info("End to init !");
	}
	
	public static void destroy() throws KeelBeanException
	{
		LOGGER.info("Application context stop by ShutdownHook!");
		classPathXmlApplicationContext.destroy();
	}
	
	public static Object getInstance(String interfaceClassName) throws KeelBeanException
	{
		if(classPathXmlApplicationContext==null) throw new KeelBeanException("KeelBeanFactory have not be inited!");
		try{
			return classPathXmlApplicationContext.getBean(interfaceClassName);
		}catch(BeansException ex){
			throw new KeelBeanException(ex);
		}
	}
	
	public static <T> T getInstance(Class<T> requiredType) throws KeelBeanException
	{
		if(classPathXmlApplicationContext==null) throw new KeelBeanException("KeelBeanFactory have not be inited!");
		try{
			return classPathXmlApplicationContext.getBean(requiredType);
		}catch(BeansException ex){
			throw new KeelBeanException(ex);
		}
	}
	
	public static <T> T getInstance(String interfaceClassName,Class<T> requiredType) throws KeelBeanException
	{
		if(classPathXmlApplicationContext==null) throw new KeelBeanException("KeelBeanFactory have not be inited!");
		try{
			return classPathXmlApplicationContext.getBean(interfaceClassName, requiredType);
		}catch(BeansException ex){
			throw new KeelBeanException(ex);
		}
	}
	
}
